package com.sync.utils.project.message.controller;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.sync.utils.framework.result.R;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.Collection;
import java.util.Date;

/**
 * 长轮询测试
 *
 * @Author YWF
 * @Date 2023/8/31 11:28
 */
@Controller
@RequestMapping("/polling")
public class PollingController {

    // 存放监听某个Id的长轮询集合
    // 线程同步结构
    public static Multimap<String, DeferredResult<R>> watchRequests = Multimaps.synchronizedMultimap(HashMultimap.create());

    private static final long TIME_OUT = 10000L;

    /**
     * 长轮询消息监听
     * @param id
     * @return
     */
    @GetMapping(path = "watch/{id}")
    @ResponseBody
    public DeferredResult<R> watch(@PathVariable("id") String id){
        //延迟对象设置延时时间
        DeferredResult<R> deferredResult = new DeferredResult<>(TIME_OUT);
        //异步请求完成时，移除key，防止内存溢出
        deferredResult.onCompletion(()->{
            watchRequests.remove(id,deferredResult);
        });
        //注册长轮询请求
        watchRequests.put(id, deferredResult);
        return deferredResult;
    }

    /**
     * 长轮询消息推送
     * @param id
     * @return
     */
    @GetMapping(path = "publish/{id}")
    @ResponseBody
    public R publish(@PathVariable("id") String id){
        if (watchRequests.containsKey(id)){
            Collection<DeferredResult<R>> deferredResults = watchRequests.get(id);
            for (DeferredResult<R> deferredResult : deferredResults) {
                R data = R.ok().data("我更新了" + new Date());
                deferredResult.setResult(data);
            }
        }
        return R.ok();
    }

}
